package cn.dida.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.dida.core.SpringApplicationContext;
import cn.dida.exception.BizzException;
import cn.dida.model.HttpResponseBodyWrapper;
import cn.dida.model.Pageable;
import cn.dida.model.Product;
import cn.dida.model.UserSession;
import cn.dida.service.ProductService;
import cn.dida.util.DateUtils;
import cn.dida.util.ExcelUtil;
/**
 * 产品管理
 * @author weiwei
 *
 */
@Controller
public class ProductController extends BaseController {
    @Autowired
    private ProductService productService;

    /**
     * 产品列表
     * @param request
     * @param keyword 查询条件
     * @param state 状态：1使用中，2已停用
     * @param page 分页游标
     * @return ModelAndView 产品列表页面
     * @throws Exception
     */
    @GetMapping("/product")
    public ModelAndView product(HttpServletRequest request, String keyword, Integer state, Integer page) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);

        page = (page == null || page < 1) ? 1 : page;
        keyword = StringUtils.trimToEmpty(keyword);
        Pageable<Product> productList = productService.queryProduct(userSession.getCompanyId(), keyword, state, page);

        model.put("productList", productList);
        model.put("keyword", keyword);
        model.put("state", state);
        return new ModelAndView("product_list").addAllObjects(model);
    }

    /**
     * 产品数据导出
     * @param request
     * @param response
     * @param keyword 查询条件
     * @param state 状态：1使用中，2已停用
     * @return 
     * @throws IOException
     */
    @GetMapping("/product/export")
    public String product_export(HttpServletRequest request, HttpServletResponse response, String keyword, Integer state) throws IOException {
        Environment env = SpringApplicationContext.getEnvironment();
        String str = env.getProperty("pic.domain");
        UserSession userSession = getUserSession(request);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(keyword)) {
            //关键字：名称、编号、条码、品牌
            paramMap.put("keyword", keyword);
        }
        if (state != null) {
            //状态：1使用中，2已封存
            paramMap.put("state", state);
        }

        List<Product> exportList = productService.queryProductForExport(userSession.getCompanyId(), keyword, state);

        String fileName = "产品数据导出" + DateUtils.dateToString(Calendar.getInstance().getTime(), "yyyy-MM-dd");

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(exportList.size());

        Map<String, Object> fmap = null;
        for (Product product : exportList) {
            fmap = new HashMap<String, Object>();
            Long tid = NumberUtils.toLong(product.getId().toString(), 0L);
            fmap.put("id", tid);
            fmap.put("name", product.getName());

            fmap.put("image", str + product.getPictures().split(",")[0]);

            fmap.put("number", product.getNumber());
            fmap.put("barcode", product.getBarcode());
            fmap.put("brandName", product.getBrandName());
            if (product.getState() == 1) {
                fmap.put("state", "使用中");
            } else if (product.getState() == 2) {
                fmap.put("state", "已封存");
            }
            fmap.put("createTime", product.getCreateTime());
            fmap.put("createStaffAccount", product.getCreateStaffAccount());

            list.add(fmap);
        }

        String columnNames[] = {"ID", "产品名称", "产品样图", "产品编号", "条形码", "品牌", "状态", "新增时间", "操作人"};//列名
        String keys[] = {"id", "name", "image", "number", "barcode", "brandName", "state", "createTime", "createStaffAccount"};//map中的key
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ExcelUtil.createWorkBook(list, keys, columnNames).write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        // 设置response参数，可以打开下载页面
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            // Simple read/write loop.
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
                bos.flush();
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }

        return null;
    }

    /**
     * 新增产品
     * @param request
     * @param product 产品实体信息
     * @return HttpResponseBodyWrapper 封装操作标记（ true新增成功，false新增失败）
     * @throws Exception
     */
    @ResponseBody
    @PostMapping("/product")
    public HttpResponseBodyWrapper postBrand(HttpServletRequest request, @RequestBody Product product) throws Exception {
        //Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);


        product.setName(StringUtils.trimToNull(product.getName()));
        product.setNumber(StringUtils.trimToNull(product.getNumber()));
        product.setBarcode(StringUtils.trimToNull(product.getBarcode()));


        product.setCompanyId(userSession.getCompanyId());
        product.setCreateStaffId(userSession.getId());

        if (product.getName() == null || "".equals(product.getName().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品名称");
        }
        if (product.getNumber() == null  || "".equals(product.getNumber().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品编号");
        }
        if (product.getBarcode() == null  || "".equals(product.getBarcode().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品条码");
        }
        if (product.getBrandId() == null  || product.getBrandId()<=0) {
            throw new BizzException(BizzException.error_code_invalid_params, "请选择产品品牌");
        }
        if (product.getPbcId() == null  || product.getPbcId()<=0) {
            throw new BizzException(BizzException.error_code_invalid_params, "请选择产品规格");
        }
        if (!Pattern.matches("[a-zA-Z\\d]{1,}", product.getNumber())) {
            throw new BizzException(BizzException.error_code_invalid_params, "产品编号仅支持字母和数字组合");
        }
        if (!Pattern.matches("[a-zA-Z\\d]{1,}", product.getBarcode())) {
            throw new BizzException(BizzException.error_code_invalid_params, "产品条码仅支持字母和数字组合");
        }
        if (productService.getProductByNumber(userSession.getCompanyId(), product.getNumber()) != null) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在编号为【" + product.getNumber() + "】的产品");
        }
        if (productService.getProductByBarcode(userSession.getCompanyId(), product.getBarcode()) != null) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在条码为【" + product.getBarcode() + "】的产品");
        }
        if (productService.getProductByName(userSession.getCompanyId(), product.getName()) != null) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在名为【" + product.getName() + "】的产品");
        }

        Boolean result = productService.insertProduct(product);
        return new HttpResponseBodyWrapper(result);
    }

    /**
     * 根据编码获取产品信息
     * @param request
     * @param number 产品编码
     * @return HttpResponseBodyWrapper 封装单个产品信息
     * @throws Exception
     */
    @ResponseBody
    @GetMapping("/product/{number}")
    public HttpResponseBodyWrapper getBrand(HttpServletRequest request, @PathVariable String number) throws Exception {
       // Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);
        Product result = productService.getProductByNumber(userSession.getCompanyId(), number);
        return new HttpResponseBodyWrapper(result);
    }

    /**
     * 更新产品
     * @param request
     * @param product 产品实体信息
     * @return HttpResponseBodyWrapper 封装操作标记（ true更新成功，false更新失败）
     * @throws Exception
     */
    @ResponseBody
    @PutMapping("/product/{number}")
    public HttpResponseBodyWrapper putBrand(HttpServletRequest request, @RequestBody Product product) throws Exception {
        //Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);

        product.setName(StringUtils.trimToNull(product.getName()));
        product.setNumber(StringUtils.trimToNull(product.getNumber()));
        product.setBarcode(StringUtils.trimToNull(product.getBarcode()));

        if (product.getName() == null || "".equals(product.getName().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品名称");
        }
        if (product.getNumber() == null || "".equals(product.getNumber().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品编号");
        }
        if (product.getBarcode() == null || "".equals(product.getBarcode().trim())) {
            throw new BizzException(BizzException.error_code_invalid_params, "请输入产品条码");
        }
        if (product.getBrandId() == null || product.getBrandId()<=0) {
            throw new BizzException(BizzException.error_code_invalid_params, "请选择产品品牌");
        }
        if (product.getPbcId() == null || product.getPbcId()<=0) {
            throw new BizzException(BizzException.error_code_invalid_params, "请选择产品规格");
        }
        if (!Pattern.matches("[a-zA-Z\\d]{1,}", product.getNumber())) {
            throw new BizzException(BizzException.error_code_invalid_params, "产品编号仅支持字母和数字组合");
        }
        if (!Pattern.matches("[a-zA-Z\\d]{1,}", product.getBarcode())) {
            throw new BizzException(BizzException.error_code_invalid_params, "产品条码仅支持字母和数字组合");
        }
        Product product1 = productService.getProductByNumber(userSession.getCompanyId(), product.getNumber());
        if (product1 != null && product1.getId().intValue() != product.getId().intValue()) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在编号为【" + product.getNumber() + "】的产品");
        }
        Product product2 = productService.getProductByBarcode(userSession.getCompanyId(), product.getBarcode());
        if (product2 != null && product2.getId().intValue() != product.getId().intValue()) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在条码为【" + product.getName() + "】的产品");
        }
        Product product3 = productService.getProductByName(userSession.getCompanyId(), product.getName());
        if (product3 != null && product3.getId().intValue() != product.getId().intValue()) {
            throw new BizzException(BizzException.error_code_invalid_params, "已存在名为【" + product.getName() + "】的产品");
        }

        product.setCompanyId(userSession.getCompanyId());
        Boolean result = productService.updateProduct(product);
        return new HttpResponseBodyWrapper(result);
    }

    /**
     * 删除产品
     * @param request
     * @param number 产品编号
     * @return HttpResponseBodyWrapper 封装操作标记（ true删除成功，false删除失败）
     * @throws Exception
     */
    @ResponseBody
    @DeleteMapping("/product/{number}")
    public HttpResponseBodyWrapper deleteBrand(HttpServletRequest request, @PathVariable String number) throws Exception {
       // Map<String, Object> model = new HashMap<String, Object>();
        UserSession userSession = getUserSession(request);
        Boolean result = productService.deleteProductByNumber(userSession.getCompanyId(), number);
        return new HttpResponseBodyWrapper(result);
    }
}
